﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using FacebookWrapper.ObjectModel;
using Ex3.Logic;

namespace Ex3
{
    public partial class RankPhotosForm : Form
    {
        private User User { get; set; }

        private Photo CurrentPhoto { get; set; }

        private RankPhotos RankedPhotos { get; set; }

        private RankPhotos NewRankedPhotos { get; set; }

        private RankPhotos UpdatedPhotos { get; set; }

        public RankPhotos ReturnPhotos { get; private set; }

        public RankPhotosForm(User i_User)
        {
            this.InitializeComponent();
            this.User = i_User;
            this.NewRankedPhotos = new RankPhotos();
            this.UpdatedPhotos = new RankPhotos();
            this.RankedPhotos = new RankPhotos();
            this.ReturnPhotos = new RankPhotos();
        }

        public RankPhotosForm(User i_User, RankPhotos i_Photos)
        {
            this.InitializeComponent();
            this.User = i_User;
            this.RankedPhotos = i_Photos;
            this.NewRankedPhotos = new RankPhotos();
            this.UpdatedPhotos = new RankPhotos();
            this.ReturnPhotos = i_Photos;
        }

        private void RankPhotosForm_Load(object sender, EventArgs e)
        {
            this.SelectPhoto();
        }

        /// <summary>
        /// Choses a photo to rank
        /// </summary>
        private void SelectPhoto()
        {
            int maxPhotos = this.User.PhotosTaggedIn.Count;
            Random rand = new Random();
            int randomPhotoNumber = rand.Next(0, maxPhotos);

            this.CurrentPhoto = this.User.PhotosTaggedIn[randomPhotoNumber];
            this.pictureBoxMyPhoto.LoadAsync(this.User.PhotosTaggedIn[randomPhotoNumber].URL);
        }

        private void pictureBoxStars_Click(object sender, EventArgs e)
        {
            PictureBox selectedStar = (PictureBox)sender;

            foreach (PictureBox currentPictureBox in this.panelStars.Controls)
            {
                if ((currentPictureBox != selectedStar) && (currentPictureBox.BorderStyle == BorderStyle.Fixed3D))
                {
                    currentPictureBox.BorderStyle = BorderStyle.None;
                }
                else if ((currentPictureBox == selectedStar) && (currentPictureBox.BorderStyle != BorderStyle.Fixed3D))
                {
                    currentPictureBox.BorderStyle = BorderStyle.Fixed3D;
                }
            }
        }

        private void buttonNext_Click(object sender, EventArgs e)
        {
            this.getNextPhoto();
        }

        private void getNextPhoto()
        {
            this.SelectPhoto();
            this.uploadPhotoInformation();
        }

        private void buttonSave_Click(object sender, EventArgs e)
        {
            int numOfStars = this.getStars();
            if ((numOfStars < 1) || (numOfStars > 5))
            {
                MessageBox.Show("Please select rank the photo before saving", "Photo was not ranked");
            }
            else
            {
                string currentPhotoID = this.CurrentPhoto.Id;
                if ((this.RankedPhotos != null) && this.RankedPhotos.ContainsID(currentPhotoID))
                {
                    if ((this.RankedPhotos != null) && ((RankedPhoto)this.RankedPhotos[currentPhotoID]).RankedStars 
                        != (Common.Stars)numOfStars)
                    {
                        this.UpdatedPhotos.Rank(this.CurrentPhoto, (Common.Stars) numOfStars);
                    }
                }
                else if (this.NewRankedPhotos.ContainsID(currentPhotoID))
                {
                    RankedPhoto photo = this.NewRankedPhotos.GetPhotoByID(currentPhotoID);
                    
                    if (photo != null)
                    {
                        this.NewRankedPhotos[currentPhotoID].RankedStars = (Common.Stars)numOfStars;
                    }
                }
                else
                {
                    this.NewRankedPhotos.Rank(this.CurrentPhoto, (Common.Stars)numOfStars);
                }

                this.getNextPhoto();
            }
        }

        /// <summary>
        /// Gets a photo information - rank value
        /// </summary>
        private void uploadPhotoInformation()
        {
            RankedPhoto ranked = this.getRankedPhotoFromPhoto(this.CurrentPhoto);
            if (ranked == null)
            {
                this.resetFormForNewPhoto();
            }
            else
            {
                foreach (PictureBox currentPictureBox in this.panelStars.Controls)
                {
                    if (int.Parse(currentPictureBox.Tag.ToString()) == (int)ranked.RankedStars)
                    {
                        currentPictureBox.BorderStyle = BorderStyle.Fixed3D;
                    }
                    else
                    {
                        currentPictureBox.BorderStyle = BorderStyle.None;
                    }
                }
            }   
        }

        public RankedPhoto getRankedPhotoFromPhoto(Photo i_CurrentPhoto)
        {
            RankedPhoto ranked = null;
            
            ranked = this.NewRankedPhotos.GetPhotoByID(i_CurrentPhoto.Id);
            if (ranked == null)
            {
                ranked = this.RankedPhotos.GetPhotoByID(i_CurrentPhoto.Id);
                if (ranked == null)
                {
                    ranked = this.UpdatedPhotos.GetPhotoByID(i_CurrentPhoto.Id);
                }
            }

            return ranked;
        }

        /// <summary>
        /// If the photo is not ranked - shows unselected stars
        /// </summary>
        public void resetFormForNewPhoto()
        {
            foreach (PictureBox currentPictureBox in this.panelStars.Controls)
            {
                 currentPictureBox.BorderStyle = BorderStyle.None;
            }
        }

        private void saveAll()
        {
            this.ReturnPhotos = this.getPhotosToSave();
            FileRankPhotos filePhotos = new FileRankPhotos(this.ReturnPhotos);
            
            try
            {
                filePhotos.Save(this.User);
                MessageBox.Show("The photos where ranked successfully", "Saving photos");
            }
            catch
            {
                MessageBox.Show("Error saving the photos", "Error");
            }
        }

        private RankPhotos getPhotosToSave()
        {
            RankPhotos photosToSave = new RankPhotos();

            foreach (RankedPhoto currentRankedPhotos in this.RankedPhotos)
            {
                if (!this.UpdatedPhotos.ContainsID(currentRankedPhotos.ID))
                {
                    photosToSave.AddPhoto(currentRankedPhotos);
                }
            }

            foreach (RankedPhoto currentUpdated in this.UpdatedPhotos)
            {
                photosToSave.AddPhoto(currentUpdated);
            }

            foreach (RankedPhoto newRankedPhoto in this.NewRankedPhotos)
            {
                photosToSave.AddPhoto(newRankedPhoto);
            }

            return photosToSave;
        }

        private int getStars()
        {
            int numberOfStars = 0;
            foreach (PictureBox currentPictureBox in this.panelStars.Controls)
            {
                if (currentPictureBox.BorderStyle == BorderStyle.Fixed3D)
                {
                    numberOfStars = int.Parse(currentPictureBox.Tag.ToString());
                }
            }

            return numberOfStars;
        }

        public Photo GetPhotoByID(string i_ID)
        {
            foreach (Photo currentPhoto in this.User.PhotosTaggedIn)
            {
                if (currentPhoto.Id == i_ID)
                {
                    return currentPhoto;
                }
            }

            return null;
        }

        private void RankPhotosForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            this.saveAll();
        }
    }
}
